<?php
/**
 * @package site
 */
class MatchingBonus extends DataObject implements PermissionProvider {
    private static $singular_name = "Matching Bonus";
    private static $plural_name = "Matching Bonuses";

    private static $payout_table = array(
        1 => array(
            'downline' => 1,
            'downline3k' => 0,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        2 => array(
            'downline' => 1,
            'downline3k' => 0,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        3 => array(
            'downline' => 2,
            'downline3k' => 0,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        4 => array(
            'downline' => 2,
            'downline3k' => 0,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        5 => array(
            'downline' => 3,
            'downline3k' => 0,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        6 => array(
            'downline' => 3,
            'downline3k' => 0,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        7 => array(
            'downline' => 3,
            'downline3k' => 1,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        8 => array(
            'downline' => 3,
            'downline3k' => 1,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        9 => array(
            'downline' => 3,
            'downline3k' => 2,
            'rank' => array(
				'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
			),
            'percentage' => 0.02
        ),
        10 => array(
            'downline' => 3,
            'downline3k' => 2,
            'rank' => array(
				'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
			),
            'percentage' => 0.02
        ),
        11 => array(
            'downline' => 3,
            'downline3k' => 3,
            'rank' => array(
				'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
			),
            'percentage' => 0.02
        ),
        12 => array(
            'downline' => 3,
            'downline3k' => 3,
            'rank' => array(
				'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
			),
            'percentage' => 0.02
        )
    );
	
	private static $payout_table_201503 = array(
        1 => array(
            'downline' => 1,
            'downline3k' => 0,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        2 => array(
            'downline' => 1,
            'downline3k' => 0,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        3 => array(
            'downline' => 2,
            'downline3k' => 0,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        4 => array(
            'downline' => 2,
            'downline3k' => 0,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        5 => array(
            'downline' => 3,
            'downline3k' => 0,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        6 => array(
            'downline' => 3,
            'downline3k' => 0,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        7 => array(
            'downline' => 3,
            'downline3k' => 1,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        8 => array(
            'downline' => 3,
            'downline3k' => 1,
            'rank' => array(
                'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
            ),
            'percentage' => 0.02
        ),
        9 => array(
            'downline' => 3,
            'downline3k' => 2,
            'rank' => array(
				'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
			),
            'percentage' => 0.02
        ),
        10 => array(
            'downline' => 3,
            'downline3k' => 2,
            'rank' => array(
				'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
			),
            'percentage' => 0.02
        ),
        11 => array(
            'downline' => 3,
            'downline3k' => 3,
            'rank' => array(
				'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
			),
            'percentage' => 0.02
        ),
        12 => array(
            'downline' => 3,
            'downline3k' => 3,
            'rank' => array(
				'level1',
                'level2',
                'level3',
                'level4',
                'level5',
                'level6'
			),
            'percentage' => 0.02
        )
    );

    private static $db = array(
        'Percentage' => 'Percentage',
        'Downline1K' => 'Int',
        'Downline3K' => 'Int',
        'Level' => 'Int',
        'Debit' => 'Currency',
        'Credit' => 'Currency',
        'ForwardBalance' => 'Currency',
        'Remark' => 'Varchar(250)'
    );

    private static $has_one = array(
        'Batch' => 'BonusBatch',
        'Member' => 'Member',
        'Group' => 'Group',
        'PassBy' => 'Member'
    );

    private static $many_many = array(
        'InvestProgramPayout' => 'InvestProgramPayout',
        'BonusAccounts' => 'BonusAccount',
		'ProductAccounts' => 'ProductAccount',
        'TradeCoinAccounts' => 'TradeCoinAccount',
        'UpgradeAccounts' => 'UpgradeAccount'
    );

    private static $default_sort = "Created DESC, ID DESC";

    private static $searchable_fields = array(
        'Batch.Code',
        'Member.FirstName',
        'Member.Surname',
        'Member.Username',
        'GroupID',
        'Percentage',
        'Level',
        'Remark'
    );

    private static $summary_fields = array(
        'Batch.Code',
        'Member.Username',
        'Member.Name',
        'Description',
        'AmountText',
        'ForwardBalance',
        'Remark'
    );

    private static $casting = array('Balance' => 'Currency');

    public function fieldLabels($includerelations = true) {
        $labels = parent::fieldLabels($includerelations);

        $labels['Description'] = _t('MatchingBonus.DESCRIPTION', 'Description');
        $labels['Percentage'] = _t('MatchingBonus.PERCENTAGE', 'Percentage');
        $labels['Percentage.Nice'] = _t('MatchingBonus.PERCENTAGE', 'Percentage');
        $labels['Downline1K'] = _t('MatchingBonus.DOWNLINE_1K', 'Downline 1K');
		$labels['Downline3K'] = _t('MatchingBonus.DOWNLINE_3K', 'Downline 3K');
        $labels['Level'] = _t('MatchingBonus.LEVEL', 'Level');
        $labels['Credit'] = _t('MatchingBonus.CREDIT', 'Credit');
		$labels['Debit'] = _t('MatchingBonus.DEBIT', 'Debit');
        $labels['AmountText'] = _t('MatchingBonus.AMOUNT', 'Amount');
        $labels['ForwardBalance'] = _t('MatchingBonus.BALANCE', 'Balance');
        $labels['Remark'] = _t('MatchingBonus.REMARK', 'Remark');
        $labels['Batch'] = _t('MatchingBonus.BATCH', 'Batch');
        $labels['Batch.Code'] = _t('MatchingBonus.BATCH', 'Batch');
        $labels['Group'] = _t('MatchingBonus.GROUP', 'Group');
        $labels['GroupID'] = _t('MatchingBonus.GROUP', 'Group');
        $labels['BonusAccounts'] = _t('MatchingBonus.BONUS_ACCOUNT', 'E-Bonus Accounts');
        $labels['ProductAccounts'] = _t('MatchingBonus.PRODUCT_ACCOUNT', 'E-Product Accounts');
		$labels['TradeCoinAccounts'] = _t('MatchingBonus.TRADE_COIN_ACCOUNT', 'Trade-Coin Accounts');
		$labels['UpgradeAccounts'] = _t('MatchingBonus.UPGRADE_ACCOUNT', 'E-Upgrade Accounts');
        $labels['Member.Username'] = _t('MatchingBonus.USERNAME', 'Username');
        $labels['Member'] = _t('MatchingBonus.NAME', 'Name');
        $labels['Member.Name'] = _t('MatchingBonus.NAME', 'Name');
        $labels['Member.FirstName'] = _t('MatchingBonus.FIRSTNAME', 'First Name');
        $labels['Member.Surname'] = _t('MatchingBonus.SURNAME', 'Surname');
        $labels['PassBy.Username'] = _t('MatchingBonus.PASS_BY_USERNAME', 'Pass By Username');
        $labels['PassBy'] = _t('MatchingBonus.PASS_BY_NAME', 'Pass By Name');
        $labels['PassBy.Name'] = _t('MatchingBonus.PASS_BY_NAME', 'Pass By Name');
        $labels['PassBy.FirstName'] = _t('MatchingBonus.PASS_BY_FIRSTNAME', 'Pass By First Name');
        $labels['PassBy.Surname'] = _t('MatchingBonus.PASS_BY_SURNAME', 'Pass By Surname');
        return $labels;
    }

    function onBeforeWrite() {
        parent::onBeforeWrite();
        $this->setField('ForwardBalance', $this->getBalance() + $this->Credit - $this->Debit);
    }

    function onAfterWrite() {
        parent::onAfterWrite();
		if(!$this->Member()->NoMatchingPayout){
	        if($this->Credit > 0) {
	            if(!$count = $this->BonusAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Description)->filter('Reference', $this->Batch()->Code)->filter('Credit:GreaterThan', 0)->count()) {
	                $statement_data = array(
	                    'Type' => 'Bonus',
	                    'Credit' => $this->Credit * 0.7,
	                    'Reference' => $this->Batch()->Code,
	                    'Description' => $this->Description
	                );
					
					if($this->Member()->IsExceedPayout){
						$statement_data['Credit'] = $statement_data['Credit'] * 0.5;
						
						$id = UpgradeAccount::create_statement($statement_data, $this->MemberID);
						$this->UpgradeAccounts()->add($id);
					}
	
	                $id = BonusAccount::create_statement($statement_data, $this->MemberID);
	                $this->BonusAccounts()->add($id);
	            }
	
	            if(!$count = $this->ProductAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Description)->filter('Reference', $this->Batch()->Code)->filter('Credit:GreaterThan', 0)->count()) {
	                $statement_data = array(
	                    'Type' => 'Bonus',
	                    'Credit' => $this->Credit * 0.1,
	                    'Reference' => $this->Batch()->Code,
	                    'Description' => $this->Description
	                );
	                $id = ProductAccount::create_statement($statement_data, $this->MemberID);
	                $this->ProductAccounts()->add($id);
	            }
	
				if(!$count = $this->TradeCoinAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Description)->filter('Reference', $this->Batch()->Code)->filter('Credit:GreaterThan', 0)->count()) {
	                $statement_data = array(
	                    'Type' => 'Bonus',
	                    'Credit' => $this->Credit * 0.2,
	                    'Reference' => $this->Batch()->Code,
	                    'Description' => $this->Description
	                );
	                $id = TradeCoinAccount::create_statement($statement_data, $this->MemberID);
	                $this->TradeCoinAccounts()->add($id);
	            }
	        }
	
	        if($this->Debit > 0) {
	            $statement = $this->BonusAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Description)->filter('Reference', $this->Batch()->Code)->filter('Credit:GreaterThan', 0);
	            if($statement->count() > $this->BonusAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Remark)->filter('Reference', $this->Batch()->Code)->filter('Debit:GreaterThan', 0)->count()) {
	                $statement_data = array(
	                    'Type' => $statement->Type,
	                    'Debit' => $statement->Credit,
	                    'Reference' => $statement->Reference,
	                    'Description' => $this->Remark ? $this->Remark : sprintf('Deduct - %s', $statement->Description)
	                );
	                $id = BonusAccount::create_statement($statement_data, $statement->MemberID);
	                $this->BonusAccounts()->add($id);
	            }
				
				$statement = $this->UpgradeAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Description)->filter('Reference', $this->Batch()->Code)->filter('Credit:GreaterThan', 0);
	            if($statement->count() > $this->UpgradeAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Remark)->filter('Reference', $this->Batch()->Code)->filter('Debit:GreaterThan', 0)->count()) {
	                $statement_data = array(
	                    'Type' => $statement->Type,
	                    'Debit' => $statement->Credit,
	                    'Reference' => $statement->Reference,
	                    'Description' => $this->Remark ? $this->Remark : sprintf('Deduct - %s', $statement->Description)
	                );
	                $id = UpgradeAccount::create_statement($statement_data, $statement->MemberID);
	                $this->UpgradeAccounts()->add($id);
	            }
	
	            $statement = $this->ProductAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Description)->filter('Reference', $this->Batch()->Code)->filter('Credit:GreaterThan', 0);
	            if($statement->count() > $this->ProductAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Remark)->filter('Reference', $this->Batch()->Code)->filter('Debit:GreaterThan', 0)->count()) {
	                $statement_data = array(
	                    'Type' => $statement->Type,
	                    'Debit' => $statement->Credit,
	                    'Reference' => $statement->Reference,
	                    'Description' => $this->Remark ? $this->Remark : sprintf('Deduct - %s', $statement->Description)
	                );
	                $id = ProductAccount::create_statement($statement_data, $statement->MemberID);
	                $this->ProductAccounts()->add($id);
	            }
				
				$statement = $this->TradeCoinAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Description)->filter('Reference', $this->Batch()->Code)->filter('Credit:GreaterThan', 0);
	            if($statement->count() > $this->TradeCoinAccounts()->filter('Type', 'Bonus')->filter('Description', $this->Remark)->filter('Reference', $this->Batch()->Code)->filter('Debit:GreaterThan', 0)->count()) {
	                $statement_data = array(
	                    'Type' => $statement->Type,
	                    'Debit' => $statement->Credit,
	                    'Reference' => $statement->Reference,
	                    'Description' => $this->Remark ? $this->Remark : sprintf('Deduct - %s', $statement->Description)
	                );
	                $id = TradeCoinAccount::create_statement($statement_data, $statement->MemberID);
	                $this->TradeCoinAccounts()->add($id);
	            }
	        }
        }
    }

    function getBalance() {
        return MatchingBonus::get()->filter('MemberID', $this->MemberID)->sum('Credit') - MatchingBonus::get()->filter('MemberID', $this->MemberID)->sum('Debit');
    }

    function getDescription() {
    	return _t('MatchingBonus.SHOW_DESCRIPTION', 'MATCHING BONUS FOR {percentage} (LEVEL {level}) BY {member}', '', array('percentage' => $this->dbObject('Percentage')->Nice(), 'level' => $this->Level, 'member' => $this->PassBy()->Username));
    }

    function getAmountText() {
        if($this->Credit == $this->Debit) {
            return DBField::create_field('Double', 0)->Nice();
        } else if($this->Credit > 0) {
            return sprintf('%s(+)', DBField::create_field('Double', $this->Credit)->Nice());
        } else {
            return sprintf('%s(-)', DBField::create_field('Double', $this->Debit)->Nice());
        }
    }

    function canView($member = false) {
        $extended = $this->extendedCan(__FUNCTION__, $member);
        if($extended !== null) {
            return $extended;
        }
        return Permission::check('VIEW_MatchingBonus');
    }

    function canEdit($member = false) {
        return false;
    }

    function canDelete($member = false) {
        return false;
    }

    function canCreate($member = false) {
        return false;
    }

    public function providePermissions() {
        return array(
            'VIEW_MatchingBonus' => array(
                'name' => _t('MatchingBonus.PERMISSION_VIEW', 'Allow view access right'),
                'category' => _t('MatchingBonus.PERMISSIONS_CATEGORY', 'Matching Bonus')
            )
        );
    }

}
?>
